<template>
	<div class="upload-video">
		<div
			class="upload-warp "
			:class="{
				disabled: !couldUpload,
			}"
		>
			<i class="el-icon-upload"></i>
			<div class="el-upload__text">点击上传</div>
			<div class="el-upload__tip">只能上传视频文件，且不超过{{ size }}kb</div>

			<input type="file" class="input" accept="video/*" ref="inputRef" @change="onUpload" />
		</div>
		<div class="upload-item" v-for="(item, index) in fileList" :key="index">
			<div class="title">
				<i class="el-icon-paperclip"></i>
				<div class="name">{{ item.name }}</div>

				<div class="right">
					<i class="el-icon-video-play" @click="onPreview(index)"></i>
					<i class="el-icon-delete" @click="onDelete(index)"></i>
				</div>
			</div>
		</div>
		<div class="upload-item loading" v-for="(item, index) in loadingList" :key="index">
			<div class="title">
				<i class="el-icon-loading"></i>
				<div class="name">{{ item.name }}</div>
			</div>
			<el-progress
				class="el-progress"
				:stroke-width="5"
				:percentage="item.progress"
				:show-text="false"
				:color="[
					{ color: '#f56c6c', percentage: 40 },
					{ color: '#E88F21', percentage: 80 },
					{ color: '#67c23a', percentage: 100 },
				]"
			></el-progress>
		</div>

		<el-dialog append-to-body modal-append-to-body :visible.sync="preview.visible" :title="preview.name" width="550px">
			<video :src="preview.url" controls="controls" style="width: 100%;"></video>
		</el-dialog>
	</div>
</template>

<script>
import request from "@/common/request"

export default {
	name: "upload-video",
	model: {
		prop: "formData",
		event: "update:formData",
	},
	props: {
		formData: {
			type: Object,
			default: () => ({}),
		},
		name: {
			type: String,
		},
		size: {
			type: Number,
		},
		limit: {
			type: [Number, String],
			default: 5,
		},
		returnType: {
			type: String,
			default: "array", // json string array
		},
	},
	data() {
		return {
			baseUrl: window.$conf.commonConf.baseUrl,

			loadingList: [],

			preview: {
				visible: false,
				url: "",
				name: "",
			},
		}
	},
	computed: {
		couldUpload() {
			if (this.limit < 0) {
				return true
			}
			return this.fileList.length + this.loadingList.length < this.limit
		},
		value: {
			get() {
				return this.formData
			},
			set(value) {
				this.$emit("update:formData", value)
			},
		},
		fileList() {
			const file = this.value[this.name]
			if (typeof file === "string" && file.length > 0) {
				if (this.returnType === "json") {
					return JSON.parse(file)
				} else if (this.returnType === "string") {
					return file.split(",").map(item => {
						return {
							url: item,
							name: item.split("/").pop(),
						}
					})
				} else {
					return [
						{
							url: file,
							name: file.split("/").pop(),
						},
					]
				}
			} else if (Array.isArray(file)) {
				return file.map(item => {
					if (typeof item === "string") {
						return {
							url: item,
							name: item.split("/").pop(),
						}
					}
					return item
				})
			}
			return []
		},
	},
	methods: {
		onUpload(event) {
			const file = event.target.files[0]
			event.target.value = ""
			if (!file) {
				return
			}

			const id = Math.random()
				.toString(36)
				.slice(5)
			this.loadingList.push({
				name: file.name,
				file,
				progress: 0,
				id,
			})

			this.toUpload(file, id)
		},

		async toUpload(file, id) {
			try {
				const formData = new FormData()
				formData.append("upfile", file)
				const { code, data, msg } = await request("post", window.$conf.commonConf.baseUrl + "/system/oss/upload", formData, {
					onUploadProgress: progressEvent => {
						const progress = Math.round((progressEvent.loaded / progressEvent.total) * 100)
						this.loadingList.forEach(item => {
							if (item.id === id) {
								item.progress = progress >= 100 ? 99 : progress
							}
						})

						// if (progress === 100) {
						// 	this.loadingList = this.loadingList.filter(item => item.id !== id)
						// }
					},
				})
				this.loadingList = this.loadingList.filter(item => item.id !== id)
				if (code === 0) {
					this.value[this.name] = this.fileList.concat(data)
					this.$emit("upload-success", [
						data,
						{
							raw: file,
							name: file.name,
							size: file.size,
							type: file.type,
						},
					])
				} else {
					throw new Error(msg)
				}
			} catch (error) {
				this.$message.error(error.message)
			}
		},

		onDelete(index) {
			const list = [].concat(this.fileList)
			list.splice(index, 1)
			this.value[this.name] = list
		},
		onPreview(index) {
			this.preview.url = this.fileList[index].url
			this.preview.name = this.fileList[index].name
			this.preview.visible = true
		},
	},
	watch: {
		"preview.visible"() {
			if (!this.preview.visible) {
				this.preview.url = ""
				this.preview.name = ""
			}
		},
	},
}
</script>

<style lang="scss" scoped>
.upload-warp {
	border: 1px dashed #d9d9d9;
	cursor: pointer;
	display: flex;
	justify-content: center;
	align-items: center;
	flex-direction: column;
	width: 360px;
	height: 180px;
	overflow: hidden;
	border-radius: 7px;
	margin-bottom: 7px;
	position: relative;
	&.disabled {
		opacity: 0.5;
		pointer-events: none;
	}
	&:hover {
		border-color: #409eff;
	}

	.el-icon-upload {
		font-size: 50px;
		color: #c0c4cc;
	}
	.el-upload__text {
		color: #409eff;
	}
	.input {
		position: absolute;
		top: 0;
		left: 0;
		width: 100%;
		height: 100%;
		opacity: 0;
		cursor: pointer;
		z-index: 99;
		::-webkit-file-upload-button {
			cursor: pointer;
		}
	}
}
.upload-item {
	padding-inline: 10px;
	border-radius: 5px;
	line-height: 36px;
	font-size: 14px;
	margin-bottom: 6px;
	&:not(.loading) {
		&:hover {
			background-color: #f5f7fa;
			.name {
				color: #409eff;
			}
		}
	}
	.title {
		display: flex;
		justify-content: flex-start;
		align-items: center;
		gap: 7px;
		.right {
			margin-left: auto;
			display: flex;
			justify-content: space-between;
			align-items: center;
			gap: 10px;
			font-size: 16px;
			.el-icon-video-play {
				&:hover {
					color: #409eff;
				}
			}
			.el-icon-delete {
				&:hover {
					color: #f56c6c;
				}
			}
			i {
				cursor: pointer;
			}
		}
		.name {
			padding-right: 10px;
			overflow: hidden;
			text-overflow: ellipsis;
			white-space: nowrap;
		}
		i {
			flex: none;
		}
	}
}
</style>
